//==============================================================================
// BLASTWrapper.hh 
//
//==============================================================================
//.......1.........2.........3.........4.........5.........6.........7.........8
//

#ifndef _BLAST_RESULTS
#define _BLAST_RESULTS

#include "LocalSTL.hh"
#include "Table.hh"
#include "Sequence.hh"
#include "ParseUtils.hh"
#include "RandomNumberGenerator.hh"
#include "SearchResult.hh"
#include "FASTAFile.hh"
#include "MiscUtils.hh"

//-----------------------------------------------------------------------------
// * BLASTSearchResult
//-----------------------------------------------------------------------------
//
// BLAST
// returns the maximal amount of information, so the class is taylored to 
// that, but it can also be used for searches which return less information.  
// Clearly, this is not a space efficient representation, but this is 
// outweighed typically by the convenience of being able to write code that 
// uses a generic search result class. 

class BLASTSearchResult: public SearchResult{
public:
  string mQueryName;
  string mSubjectName;

  double mScoreBits;                 
  double mExpect;              // Expectation value for match, in BLAST terms. 

  int    mIdentitiesNum;
  int    mIdentitiesDen;

  //long   mQueryStart;
};

class BLASTSearchResultVec: public vector<BLASTSearchResult>{
public:
  vector<string> mSubjects;
  vector<string> mQueries;

};

//-----------------------------------------------------------------------------
// * BLASTWrapper
//-----------------------------------------------------------------------------
// Wrapper for BLAST, including functionality to initiate BLAST and parse results.
// There is a nice example of the use of this handy class in the tutorials directory. 
//
// All searches return a BLASTSearchResultVec class in order to provide a mechanism
// to transparently substitute a BLAST search engine with, say, a suffix tree 
// search engine, or hash search engine, or alignment search engine, all of 
// which also return a BLASTSearchResultVec as output.
// 
// The plan, when I get a chance, is to have each of these search engines 
// inherit from the abstract base class SequenceSearchEngine so that swapping
// them out is maximally transparent.
//
//
//
class BLASTWrapper{
public:
  BLASTWrapper();

  string mType;
  string mView;
  bool   mbViewByRead;

  string mOutFileName;
  string mQueryFileName;
  string mBLASTDBName;

  string mParseType;

  int    mSampleSize;

  float mElapsedTime;

  SequenceVector *mpSamplesVec;   // Pointer to query samples.

  BLASTSearchResultVec mResultsVec;

  void ParseView0(string FileName,BLASTSearchResultVec &R);
  void ParseView0HTML(string FileName,BLASTSearchResultVec &R);
  void Search(string TargetName,string DBName,BLASTSearchResultVec &Results);
  void Search(SequenceVector &TargetSeq,string DBName,BLASTSearchResultVec &Results);
  void SearchConcatenatedSamples(SequenceVector &seqVec,string BLASTDB,
				 BLASTSearchResultVec &Results);

  void SetViewByRead(bool bViewByRead){mbViewByRead = bViewByRead;};

protected:

  vector<string> mKeywordList; // KJD This should not be here. 

  void InitKeywordList2(string Names[]);  // KJD This should NOT be here
  void InitFeatureNames();
  void InitHTMLFeatureNames();

  void StripReadNameSuffixes();
  void StripAccessionNumber();
  void MapSamplesToConcatenated(BLASTSearchResultVec &Results);
  void ParseBLASTOutput(BLASTSearchResultVec &R);
  void RunBLASTOnFile();
  string CreateTemporaryFileName(string &RootName);
  string CreateTemporaryFileName(char *RootName);
  void ConcatenateSamples(Sequence &target,SequenceVector &Samples);

};


  //void SortBySubjectName(); // depreciated
  //void SortByQueryName();

  //bool cmpBySubjectName(const BLASTSearchResult &a,const BLASTSearchResult &b){
  //	return(a.mSubjectName<b.mSubjectName);
  //}

  //bool cmpByQueryName(const BLASTSearchResult &a,const BLASTSearchResult &b){
  //return(a.mQueryName<b.mQueryName);
  //}

  //bool cmpByExpect(const BLASTSearchResult &a,const BLASTSearchResult &b){
  //	return(a.mExpect<b.mExpect);
  //}


  // Soon to be depreciated.....
//  string mSubjectName;        // Very expensive to save here, but convenient. 
//  string mQueryName;


#if 0
//---------------------------------------------------------------------------
// * SortBySubjectName
//---------------------------------------------------------------------------
//
void
BLASTSearchResultVec::SortBySubjectName()
{
  sort(this->begin(),this->end(),cmpBySubjectName);
}

//---------------------------------------------------------------------------
// * SortByExpect
//---------------------------------------------------------------------------
//
void
BLASTSearchResultVec::SortByExpect()
{
  stable_sort(this->begin(),this->end(),cmpByExpect);
}



//---------------------------------------------------------------------------
// * SortByQueryName
//---------------------------------------------------------------------------
//
void
BLASTSearchResultVec::SortByQueryName()
{
  stable_sort(this->begin(),this->end(),cmpByQueryName);
}
#endif



#endif











